library VoodooAbility initializer Init requires entities, utils, VoodooBuff
    /*
    --------------------------------------------------------------------------
    # 巫毒
    --------------------------------------------------------------------------
    */

    globals
        public integer ABILITY_ID = 'AOvd'
    endglobals

    private function SpellEnd takes Spell spell returns nothing
        call spell.destroy()
    endfunction

    private function SpellAction takes Spell spell returns nothing
        local real x = GetUnitX(spell.m_unit)
        local real y = GetUnitY(spell.m_unit)
        local real range = spell.m_rangeEffect
        local Buff bfd
        local VoodooBuff bfV
        local group g = NewGroup()
        local unit uf

        call GroupUnitsInArea(g, x, y, range)

        loop
            set uf = FirstOfGroup(g)
            exitwhen (uf == null)
            call GroupRemoveUnit(g, uf)

            if IsWidgetAlive(uf) /* 存活的
            */and not IsUnitType(uf, UNIT_TYPE_STRUCTURE) /* 非建筑
            */and IsUnitAlly(uf, GetOwningPlayer(spell.m_unit)) /* 盟友
            */and uf != spell.m_unit /* 不是自己
            */then

                set bfd = Unit.get(uf).getBuffById(VoodooBuff_BUFF_ID)

                if bfd <= 0 then
                    set bfV = VoodooBuff.create()
                    set bfd = bfV.m_buff

                    call bfV.setReduceRate(1.00)
                    call bfV.setDuration(1.2)
                endif
                
                call Unit.get(uf).addBuff(bfd)
            endif
        endloop

        call ReleaseGroup(g)
        set g = null
    endfunction

    private function anon_0 takes nothing returns nothing
        local Spell spell = GetTimerData(GetExpiredTimer())

        if (IsWidgetAlive(spell.m_unit)) then
            call SpellAction(spell)
        endif
    endfunction

    private function SpellFinish takes nothing returns nothing
        local Spell spell = Spell.get(SpellEvent.CastingUnit, ABILITY_ID)
        
        call SpellEnd(spell)
    endfunction

    private function SpellChannel takes nothing returns nothing
        local Spell spell

        if not (IsWidgetAlive(SpellEvent.CastingUnit)) then
            return
        endif

        set spell = Spell.create(SpellEvent.CastingUnit, ABILITY_ID)

        set spell.m_rangeEffect = 800
        set spell.m_interval = 1.0

        call TimerStart(spell.getTimer(), spell.m_interval, true, function anon_0)
    endfunction

    private function Init takes nothing returns nothing
        call RegisterSpellChannelResponse(ABILITY_ID, SpellChannel)
        //call RegisterSpellEffectResponse(ABILITY_ID, SpellEffect)

        call RegisterSpellEndCastResponse(ABILITY_ID, SpellFinish)
        call RegisterSpellFinishResponse(ABILITY_ID, SpellFinish)
    endfunction

endlibrary
